﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
using Great_Eggspectations.DAL;
using Great_Eggspectations.ViewModels;
using PagedList;

namespace Great_Eggspectations.Controllers
{
    public class TransactionController : Controller
    {
        private BirdbrainContainer db = new BirdbrainContainer();

        // GET: /Transaction/
        public ActionResult Index(Guid? partnerId, Guid? productId, int page = 1, int pageSize = 25)
        {
            IEnumerable<Transaction> transactions;
            string partnerName;
            Partner partner = db.Partners.Find(partnerId);
            if (partner != null)
            {
                partnerName = partner.Name;
                transactions = partner.Transactions;
            }
            else
            {
                partnerName = string.Empty;
                transactions = db.Transactions.Include(s => s.Partner).Include(s => s.Product);
            }

            string productName;
            Product product = db.Products.Find(productId);
            if (product != null)
            {
                productName = product.Name;
                transactions = transactions.Intersect(product.Transactions);
            }
            else
            {
                productName = string.Empty;
            }

            ViewBag.PartnerName = partnerName;
            ViewBag.PartnerId = partnerId;
            ViewBag.ProductName = productName;
            ViewBag.ProductId = productId;

            var transactionsVM = new TransactionsIndexViewModel
            {
                TransactionsIndexTableViewModel = new TransactionsIndexTableViewModel(transactions, page, pageSize)
            };
            return View(transactionsVM);
        }

        // GET: /Transaction/Details/5
        public ActionResult Details(Guid? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Transaction Transaction = db.Transactions.Find(id);
            if (Transaction == null)
            {
                return HttpNotFound();
            }
            return View(Transaction);
        }

        // GET: /Transaction/Create
        public ActionResult Create(Guid? PartnerId)
        {
            var Partner = db.Partners.SingleOrDefault(c => c.Id == PartnerId);
            ViewBag.PartnerName = Partner != null ? Partner.Name : string.Empty;

            var model = PartnerId.HasValue ? new Transaction { PartnerId = PartnerId.Value } : new Transaction();
            model.Date = DateTime.Now; 
            ViewBag.PartnerId = new SelectList(db.Partners, "Id", "Name");
            ViewBag.ProductId = new SelectList(db.Products, "Id", "Name");
            return View(model);
        }

        // POST: /Transaction/Create
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
        // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Create([Bind(Include = "Id,IsSale,Summary,Date,PartnerId,ProductId,Payment,Quantity,Details")] Transaction Transaction)
        {
            if (ModelState.IsValid)
            {
                Transaction.Id = Guid.NewGuid();
                var productId = Transaction.ProductId;
                var product = db.Products.SingleOrDefault(p => p.Id == productId);
                Transaction.Price = product.UnitPrice * Transaction.Quantity;
                db.Transactions.Add(Transaction);
                db.SaveChanges();
                updatePartnerBalance(Transaction.PartnerId);
                return RedirectToAction("Index", new { PartnerId = Transaction.PartnerId }); 
            }

            ViewBag.PartnerId = new SelectList(db.Partners, "Id", "Name", Transaction.PartnerId);
            ViewBag.ProductId = new SelectList(db.Products, "Id", "Name", Transaction.ProductId);
            return View(Transaction);
        }

        // GET: /Transaction/Edit/5
        public ActionResult Edit(Guid? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Transaction Transaction = db.Transactions.Find(id);
            if (Transaction == null)
            {
                return HttpNotFound();
            }
            ViewBag.PartnerId = new SelectList(db.Partners, "Id", "Name", Transaction.PartnerId);
            ViewBag.ProductId = new SelectList(db.Products, "Id", "Name", Transaction.ProductId);
            return View(Transaction); 
        }

        // POST: /Transaction/Edit/5
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
        // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Edit([Bind(Include = "Id,IsSale,Summary,Date,PartnerId,ProductId,Product,Payment,Quantity,Details")] Transaction Transaction)
        {
            if (ModelState.IsValid)
            {
                var productId = Transaction.ProductId;
                var product = db.Products.SingleOrDefault(p => p.Id == productId);
                Transaction.Price = product.UnitPrice * Transaction.Quantity;
                db.Entry(Transaction).State = EntityState.Modified;
                db.SaveChanges();
                updatePartnerBalance(Transaction.PartnerId);
                return RedirectToAction("Index", new { PartnerId = Transaction.PartnerId }); 
            }
            ViewBag.PartnerId = new SelectList(db.Partners, "Id", "Name", Transaction.PartnerId);
            ViewBag.ProductId = new SelectList(db.Products, "Id", "Name", Transaction.ProductId);
            return View(Transaction);
        }

        // GET: /Transaction/Delete/5
        public ActionResult Delete(Guid? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Transaction Transaction = db.Transactions.Find(id);
            if (Transaction == null)
            {
                return HttpNotFound();
            }
            return View(Transaction);
        }

        // POST: /Transaction/Delete/5
        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]
        public ActionResult DeleteConfirmed(Guid id)
        {
            Transaction Transaction = db.Transactions.Find(id);
            db.Transactions.Remove(Transaction);
            db.SaveChanges();
            updatePartnerBalance(Transaction.PartnerId);
            return RedirectToAction("Index");
        }

        private void updatePartnerBalance(Guid partnerId)
        {
            var partner = db.Partners.SingleOrDefault(p => p.Id == partnerId);
            var partnerTransactions = partner.Transactions;
            partner.Balance = partnerTransactions.Sum(t => t.Payment) - partnerTransactions.Sum(t => t.Price);
            db.Partners.Attach(partner);
            db.Entry(partner).State = EntityState.Modified;
            db.SaveChanges();
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                db.Dispose();
            }
            base.Dispose(disposing);
        }
    }
}
